#include "hdf_gpio_key.h"
#include "osal_time.h"


static KeyConfig *GetKeyConfig(struct HdfDeviceObject *device)
{
    KeyConfig *keyCfg = (KeyConfig *)OsalMemCalloc(sizeof(KeyConfig));
    CHECK_POINTER(keyCfg, "malloc key config failed");

    if (ParseKeyConfig(device->property, keyCfg) != HDF_SUCCESS) {
        HDF_LOGE("%s: parse key config failed", __func__);
        OsalMemFree(keyCfg);
        keyCfg = NULL;
    }
    return keyCfg;
}


uint16_t HW_jssj(void)
{
	uint16_t t=0;
    uint16_t intGpioNum = 5;
    uint16_t gpioValue = 0;
    int32_t ret = GpioRead(intGpioNum, &gpioValue);
	while(gpioValue == 1)
	{
		t++;
		OsalUSleep(20);
		if(t>=250) return t;
        GpioRead(intGpioNum, &gpioValue);
	}
	return t;
}

uint32_t hw_jsm;
uint8_t  hw_jsbz;

void HAL_GPIO_EXTI_Callback(void)
{
    static uint16_t Tim=0,Ok=0,Data,Num=0;
    uint16_t intGpioNum = 5;
    uint16_t gpioValue = 0;	
			while(1)
			{
                GpioRead(intGpioNum, &gpioValue);
				if (gpioValue == 1)
				{
					 Tim=HW_jssj();//»ñµÃ´Ë´Î¸ßµçÆ½Ê±¼ä

					 if(Tim>=250) break;//²»ÊÇÓÐÓÃµÄÐÅºÅ

					 if(Tim>=200 && Tim<250)
					 {
						Ok=1;//ÊÕµ½ÆðÊ¼ÐÅºÅ
					 }
					 else if(Tim>=60 && Tim<90)
					 {
						Data=1;//ÊÕµ½Êý¾Ý 1
					 }
					 else if(Tim>=10 && Tim<50)
					 {
						Data=0;//ÊÕµ½Êý¾Ý 0
					 }

					 if(Ok==1)
					 {
						hw_jsm<<=1;
						hw_jsm+=Data;

						if(Num>=32)
						{
							hw_jsbz=1;
							break;
						}
					 }

					 Num++;
				}
			}
}


static int32_t IrqHandle(uint16_t intGpioNum, void *data)
{
    int32_t ret;
    KeyDevice *device = (KeyDevice *)data;
    if (device == NULL) {
        return HDF_FAILURE;
    }
    ret = GpioDisableIrq(intGpioNum);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: disable irq failed, ret %d", __func__, ret);
        return ret;
    }

    device->ops->DataHandle(device);

    ret = GpioEnableIrq(intGpioNum);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: enable irq failed, ret %d", __func__, ret);
        return ret;
    }

    return HDF_SUCCESS;
}

static int32_t InitKeySource(KeyDevice *device)
{
    uint16_t intGpioNum = device->keyConfig->gpioNum;
    uint16_t irqFlag = device->keyConfig->irqFlag;

    int32_t ret = GpioSetDir(intGpioNum, GPIO_DIR_IN);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: gpio set dir failed, ret %d", __func__, ret);
        return ret;
    }
    ret = GpioSetIrq(intGpioNum, irqFlag | GPIO_IRQ_USING_THREAD, IrqHandle, device);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: register irq failed, ret %d", __func__, ret);
        return ret;
    }
    ret = GpioEnableIrq(intGpioNum);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: enable irq failed, ret %d", __func__, ret);
        return HDF_FAILURE;
    }

    return HDF_SUCCESS;
}

static int32_t HandleKeyEvent(KeyDevice *device)
{
    uint16_t intGpioNum = device->keyConfig->gpioNum;
    uint16_t gpioValue = 0;
    int32_t ret = GpioRead(intGpioNum, &gpioValue);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: gpio read failed, ret %d", __func__, ret);
        return HDF_FAILURE;
    }

    // if (gpioValue == GPIO_VAL_LOW) {
    //     input_report_key(driver->inputdev, KEY_POWER, 1);
    // } else if (gpioValue == GPIO_VAL_HIGH) {
    //     input_report_key(driver->inputdev, KEY_POWER, 0);
    // }
    // input_sync(driver->inputdev);
    return HDF_SUCCESS;
}

static struct KeyOps g_keyOperation = {
    .Init = InitKeySource,
    .DataHandle = HandleKeyEvent,
    .SetAbility = NULL,
};

static KeyDevice *InstanceKeyDevice(KeyConfig *keyConfig, struct HdfDeviceObject *device)
{
    KeyDevice *keyDev = (KeyDevice *)OsalMemCalloc(sizeof(KeyDevice));
    CHECK_POINTER(keyDev, "malloc keyDev failed");

    keyDev->ops = &g_keyOperation;
    keyDev->keyConfig = keyConfig;
    keyDev->hdfDevObj = device;

    return keyDev;
}

static int32_t RegisterKeyDriver(KeyDevice *device)
{
    int32_t ret;
    CHECK_POINTER_RETURN_VALUE(device->ops->DataHandle, HDF_FAILURE, "device ops init is nullptr");

    CHECK_POINTER_RETURN_VALUE(device->ops->Init, HDF_FAILURE, "device ops init is nullptr");
    ret = device->ops->Init(device);
    CHECK_RETURN_VALUE(ret, "device init failed");
    return HDF_SUCCESS;
}

static int32_t HdfKeyDriverInit(struct HdfDeviceObject *device)
{
    int32_t ret;
    HDF_LOGI("%s: enter", __func__);
    if (device == NULL) {
        return HDF_ERR_INVALID_PARAM;
    }

    KeyConfig *keyCfg = GetKeyConfig(device);
    if (keyCfg == NULL) {
        HDF_LOGE("%s: instance key config failed", __func__);
        return HDF_ERR_MALLOC_FAIL;
    }

    KeyDevice *keyDev = InstanceKeyDevice(keyCfg, device);
    //CHECK  TODO

    ret = RegisterKeyDriver(keyDev);
    if (ret != HDF_SUCCESS) {
         goto EXIT;
    }

    HDF_LOGI("%s: exit succ!", __func__);
    return HDF_SUCCESS;

EXIT:
    OsalMemFree(keyCfg);
    return HDF_FAILURE;
}

static int32_t HdfKeyDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
{
    (void)cmd;
    if (client == NULL || data == NULL || reply == NULL) {
        HDF_LOGE("%s: param is null", __func__);
        return HDF_FAILURE;
    }
    return HDF_SUCCESS;
}

static int32_t HdfKeyDriverBind(struct HdfDeviceObject *device)
{
    if (device == NULL) {
        return HDF_ERR_INVALID_PARAM;
    }
    static struct IDeviceIoService keyService = {
        .object.objectId = 1,
        .Dispatch = HdfKeyDispatch,
    };
    device->service = &keyService;
    return HDF_SUCCESS;
}

struct HdfDriverEntry g_hdfKeyEntry = {
    .moduleVersion = 1,
    .moduleName = "HDF_KEY",
    .Bind = HdfKeyDriverBind,
    .Init = HdfKeyDriverInit,
};

HDF_INIT(g_hdfKeyEntry);